import { Destroyable, Event, ObjResettingWithEvent, react, reactJson } from "earthsdk3";
import { MyProjectManager } from "../MyProjectManager";
import { reqGetModelLists, reqGetDuanmian, reqGetFangliang } from "@/api/modelser2Api";
import { ES3DTileset, ESGeoLineString, ESGeoPolygon, ESVolumeMeasurement } from "earthsdk3";
import { CzmPolylines } from "earthsdk3-cesium";

import loading from "@/api/loading";

let timer: any = null

function sampleArray(arr: any) {
    const len = arr.length;
    if (len <= 10000) {
        return arr; // 长度不足10000时直接返回原数组
    }

    const result = [];
    const step = len / 10000; // 计算采样步长
    for (let i = 0; i < 10000; i++) {
        // 计算当前采样点的索引（使用四舍五入确保均匀分布）
        const index = Math.round(i * step);
        result.push(arr[index]);
    }
    return result;
}
class ServiceResettting extends Destroyable {


    constructor(analyse: Analyse, owner: MyProjectManager) {
        super();

        const sceneObject = owner.createSceneObject(ES3DTileset) as ES3DTileset
        const id = analyse.modelLists.find((item: any) => item.name === analyse.currentModelId)?.id
        const url = owner.modelser2Manager.eSMsTileset.baseUrl + '/tile/model/service/' + id + '/' + 'tileset.json'
        sceneObject.url = url


        this.ad(sceneObject.tilesetReady.disposableOnce(() => {
            sceneObject.flyTo()
        }))

        this.ad(() => {
            sceneObject && owner.destroySceneObject(sceneObject)
        })
    }
}
// 断面分析
class duanmianResettting extends Destroyable {

    // 开始绘制事件
    private _drawEvent = this.dv(new Event());
    get drawEvent() { return this._drawEvent; }

    private _sceneObject: ESGeoLineString | undefined = undefined;
    get sceneObject() { return this._sceneObject; }
    set sceneObject(value: ESGeoLineString | undefined) { this._sceneObject = value; }

    constructor(analyse: Analyse, owner: MyProjectManager) {
        super();

        const sceneObject = owner.createSceneObject(ESGeoLineString) as ESGeoLineString
        this.sceneObject = sceneObject
        sceneObject.strokeColor = [1, 0, 0, 0.5]
        sceneObject.strokeWidth = 3
        sceneObject.strokeGround = true

        this.ad(this.drawEvent.don(() => {
            analyse.clearAnalyseInfo()
            analyse.clearPolylines()
            sceneObject.editing = false
            sceneObject.points = []
            sceneObject.editing = true


        }))

        this.ad(() => {
            sceneObject && owner.destroySceneObject(sceneObject)
        })
    }
}
// 方量分析
class fangliangResettting extends Destroyable {
    // 开始绘制事件
    private _drawEvent = this.dv(new Event());
    get drawEvent() { return this._drawEvent; }

    private _sceneObject: ESGeoPolygon | undefined = undefined;
    get sceneObject() { return this._sceneObject; }
    set sceneObject(value: ESGeoPolygon | undefined) { this._sceneObject = value; }

    constructor(analyse: Analyse, owner: MyProjectManager) {
        super();

        const sceneObject = owner.createSceneObject(ESGeoPolygon) as ESGeoPolygon
        this.sceneObject = sceneObject

        sceneObject.fillGround = true;
        sceneObject.stroked = false
        sceneObject.fillColor = [1, 0, 0, 0.5]

        this.ad(this.drawEvent.don(() => {
            analyse.clearAnalyseInfo()
            analyse.clearPolylines()
            sceneObject.editing = false
            sceneObject.points = []
            sceneObject.editing = true

        }))


        this.ad(() => {
            sceneObject && owner.destroySceneObject(sceneObject)
        })
    }
}

export class Analyse extends Destroyable {

    // 静态服务列表列表
    private _modelLists = this.dv(reactJson<any>([]));
    get modelLists() { return this._modelLists.value; }
    get modelListsChanged() { return this._modelLists.changed; }
    set modelLists(value: any) { this._modelLists.value = value; }


    // 选中的静态服务id
    private _currentModelId = this.dv(react<string>(""));
    get currentModelId() { return this._currentModelId.value; }
    get currentModelIdChanged() { return this._currentModelId.changed; }
    set currentModelId(value: string) { this._currentModelId.value = value; }


    // 选中的分析
    private _currentAnalyse = this.dv(react<any>(""));
    get currentAnalyse() { return this._currentAnalyse.value; }
    get currentAnalyseChanged() { return this._currentAnalyse.changed; }
    set currentAnalyse(value: any) { this._currentAnalyse.value = value; }

    // 持续时间
    private _duration = this.dv(react<any>(""));
    get duration() { return this._duration.value; }
    get durationChanged() { return this._duration.changed; }
    set duration(value: any) { this._duration.value = value; }

    // 挖方
    private _wafang = this.dv(react<any>(""));
    get wafang() { return this._wafang.value; }
    get wafangChanged() { return this._wafang.changed; }
    set wafang(value: any) { this._wafang.value = value; }

    // 填方
    private _tianfang = this.dv(react<any>(""));
    get tianfang() { return this._tianfang.value; }
    get tianfangChanged() { return this._tianfang.changed; }
    set tianfang(value: any) { this._tianfang.value = value; }

    // 差值点
    private _points = this.dv(react<any>(0));
    get points() { return this._points.value; }
    get pointsChanged() { return this._points.changed; }
    set points(value: any) { this._points.value = value; }


    // 错误信息
    private _errorInfo = this.dv(react<any>(""));
    get errorInfo() { return this._errorInfo.value; }
    get errorInfoChanged() { return this._errorInfo.changed; }
    set errorInfo(value: any) { this._errorInfo.value = value; }

    // 断面折线
    private _duanmianPolylines: undefined | CzmPolylines = undefined;
    get duanmianPolylines() { return this._duanmianPolylines; }
    set duanmianPolylines(value: CzmPolylines | undefined) { this._duanmianPolylines = value; }

    // 挖方折线
    private _excavationPolylines: undefined | CzmPolylines = undefined;
    get excavationPolylines() { return this._excavationPolylines; }
    set excavationPolylines(value: CzmPolylines | undefined) { this._excavationPolylines = value; }

    // 填方折线
    private _fillPolylines: undefined | CzmPolylines = undefined;
    get fillPolylines() { return this._fillPolylines; }
    set fillPolylines(value: CzmPolylines | undefined) { this._fillPolylines = value; }

    // 体积测量
    private _eSVolumeMeasurement: undefined | ESVolumeMeasurement = undefined;
    get eSVolumeMeasurement() { return this._eSVolumeMeasurement; }
    set eSVolumeMeasurement(value: ESVolumeMeasurement | undefined) { this._eSVolumeMeasurement = value; }

    // 切换静态服务
    private _serviceResettting = this.dv(new ObjResettingWithEvent(this.currentModelIdChanged, (res) => {
        const points = this.analyseResettting?.obj?.sceneObject?.points
        if (points) {
            // @ts-ignore
            this.analyseResettting.obj.sceneObject.points = []
        }
        this.clearAnalyseInfo()
        this.clearPolylines()
        if (!this.currentModelId) return undefined
        return new ServiceResettting(this, this._owner);
    }))
    get serviceResettting() { return this._serviceResettting; }


    // 切换分析
    private _analyseResettting = this.dv(new ObjResettingWithEvent(this.currentAnalyseChanged, (res) => {
        this.clearAnalyseInfo()
        this.clearPolylines()
        if (!this.currentAnalyse) return undefined
        if (this.currentAnalyse == "断面分析") {
            return new duanmianResettting(this, this._owner);
        } else if (this.currentAnalyse == "方量分析") {
            return new fangliangResettting(this, this._owner);
        }
    }))
    get analyseResettting() { return this._analyseResettting; }

    // 获取静态服务列表
    async getModelList() {
        try {
            const param = {
                "pageNum": 1,
                "pageSize": 10000000,
            };
            const res = await reqGetModelLists(param);
            // @ts-ignore
            if (res.code != 1000 || !res.data) return [];
            this.modelLists = res.data.list;
        } catch (error) {
            console.error(error);
        }
    }

    formatDuration(milliseconds: any) {
        const seconds = Math.floor(milliseconds / 1000);
        const hours = Math.floor(seconds / 3600);
        const minutes = Math.floor((seconds % 3600) / 60);
        const remainingSeconds = seconds % 60;
        return `${hours}小时${minutes}分钟${remainingSeconds}秒`;

    };

    // 设置断面Polylines
    setduanmianPolylines(points: any, height: any) {
        const czmViewer = this._owner.activeViewer;
        if (!czmViewer) return;
        // @ts-ignore
        this.duanmianPolylines = this.dv(new CzmPolylines(czmViewer))
        const dm = this.duanmianPolylines;
        dm.color = [1, 1, 0, 1]
        dm.show = false;
        dm.depthTest = false
        const polylines: any[] = []
        // 填方
        const newPoints = sampleArray(points)
        newPoints.forEach((e: any) => {
            polylines.push([[e[0], e[1], e[2]], [e[0], e[1], height]])
        })
        console.log('断面', polylines)
        // 挖方 填方线
        dm.positions = polylines
        dm.show = true;
    }


    // 设置方量Polylines
    setfangliangPolylines(points: any, height: any) {
        const czmViewer = this._owner.activeViewer;
        if (!czmViewer) return;
        // @ts-ignore
        this.excavationPolylines = this.dv(new CzmPolylines(czmViewer))
        const els = this.excavationPolylines;
        els.color = [1, 1, 0, 1]
        els.show = false;
        els.depthTest = false

        // @ts-ignore
        this.fillPolylines = this.dv(new CzmPolylines(czmViewer))
        const fls = this.fillPolylines;
        fls.color = [0, 0, 1, 1]
        fls.show = false;
        fls.depthTest = true

        // 挖方
        const excavationPolylines: any[] = []
        // 填方
        const fillPolylines: any[] = []
        const newPoints = sampleArray(points)

        newPoints.forEach((e: any) => {
            // 点位高于基准面（挖方）
            if (e[2] > height) {
                excavationPolylines.push([[e[0], e[1], e[2]], [e[0], e[1], height]])
            } else {
                fillPolylines.push([[e[0], e[1], e[2]], [e[0], e[1], height]])
            }
        })
        // console.log('挖方', excavationPolylines)
        // console.log('填方', fillPolylines)
        // 挖方 填方线
        els.positions = excavationPolylines
        fls.positions = fillPolylines
        els.show = true;
        fls.show = true;

        if (timer) {
            clearTimeout(timer)
        }
        timer = setTimeout(() => {
            els.depthTest = false
        }, 200)


    }

    // 接口分析
    async analyse(type: string, param: any) {
        this.clearPolylines()
        const startTime = new Date(); // 记录开始时间
        if (type == "断面分析") {
            try {
                const res = await reqGetDuanmian(param);
                if (res.status == "ok") {
                    loading.closeLoading()
                    const endTime = new Date(); // 记录结束时间
                    // @ts-ignore
                    const timeDiff = endTime - startTime; // 计算时间差（毫秒）
                    this.duration = this.formatDuration(timeDiff);
                    this.points = res.data.results[0].points;
                    const arr = this.points.map((item: any, index: number) => item[2])
                    const min = arr.reduce((acc: any, cur: any) => cur < acc ? cur : acc);
                    this.setduanmianPolylines(this.points, min)
                } else {
                    loading.closeLoading()
                    this.errorInfo = res.data.status;
                }
            } catch (error) {
                loading.closeLoading()
                this.errorInfo = error;
            }


        } else {
            // try {
            const res = await reqGetFangliang(param);
            if (res.status == "ok") {
                loading.closeLoading()
                const endTime = new Date(); // 记录结束时间
                // @ts-ignore
                const timeDiff = endTime - startTime; // 计算时间差（毫秒）
                this.duration = this.formatDuration(timeDiff);
                this.wafang = res.data.results[0].wafang;
                this.tianfang = res.data.results[0].tianfang;
                this.points = res.data.results[0].points;
                // @ts-ignore
                const ps = this.analyseResettting.obj.sceneObject.points as any
                const arr = ps.map((item: any, index: number) => item[2])
                const min = Math.min(...arr)
                const max = Math.max(...arr)
                this.setfangliangPolylines(this.points, (max + min) / 2)
            } else {
                loading.closeLoading()
                this.errorInfo = res.data.status;
            }
            // } catch (error) {
            //     loading.closeLoading()
            //     this.errorInfo = error;
            // }
        }
    }

    // 体积测量
    async volumeMeasurement(param: any) {
        this.clearPolylines()

        this.eSVolumeMeasurement = this._owner.createSceneObject(ESVolumeMeasurement) as ESVolumeMeasurement
        const ev = this.eSVolumeMeasurement
        // @ts-ignore
        ev.points = param.points
        ev.planeHeight = param.planeHeight
        ev.gridWidth = param.gridWidth
        ev.stroked = false

        ev.start()
        const startTime = new Date(); // 记录开始时间
        loading.showLoading("开始分析，请稍后...")

        let timer: any
        const czmViewer = this._owner.activeViewer;

        ev.dispose(ev.progressChanged.don(() => {
            console.log("分析进度：" + ev.progress + "%")
            if (ev.progress == 100) {
                loading.closeLoading()
                const endTime = new Date(); // 记录结束时间
                // @ts-ignore
                const timeDiff = endTime - startTime; // 计算时间差（毫秒）
                this.duration = this.formatDuration(timeDiff);

                timer = setTimeout(() => {
                    this.wafang = ev.cutVolume;
                    this.tianfang = ev.fillVolume;
                    // @ts-ignore
                    this.points = czmViewer?.getEngineObject(ev).geoVolumeMeasurement.gridPoints;
                }, 200)
                ev.dispose(() => timer && clearTimeout(timer))
            }
        }))



    }

    clearAnalyseInfo() {
        this.duration = "";
        this.points = [];
        this.errorInfo = "";
        this.wafang = "";
        this.tianfang = "";

    }

    clearPolylines() {
        if (this.excavationPolylines) {
            let els = this.excavationPolylines as any;
            els && els.destroy();
            els = undefined;
        }
        if (this.fillPolylines) {
            let fls = this.fillPolylines as any;
            fls && fls.destroy();
            fls = undefined;

        }
        if (this.duanmianPolylines) {
            let dm = this.duanmianPolylines as any;
            dm && dm.destroy();
            dm = undefined;

        }
        if (this.eSVolumeMeasurement) {
            let ev = this.eSVolumeMeasurement as any;
            ev && this._owner.destroySceneObject(ev);
            ev = undefined;

        }

        this.duration = "";
        this.wafang = 0;
        this.tianfang = 0;
        this.points = [];
    }

    clear() {
        this.modelLists = [];
        this.currentModelId = "";
        this.currentAnalyse = "";
        this.clearAnalyseInfo()
        this.clearPolylines()
    }


    constructor(private _owner: MyProjectManager) {
        super();
        // setTimeout(() => {
        //     // console.log(new CzmPolylines(this._owner.activeViewer as any));
        //     const czmViewer = this._owner.activeViewer;
        //     if (!czmViewer) return;
        //     // @ts-ignore
        //     this.excavationPolylines = this.dv(new CzmPolylines(czmViewer))
        //     const els = this.excavationPolylines;
        //     els.color = [1, 1, 0, 1]
        //     els.show = false;
        //     els.depthTest = false

        //     // @ts-ignore
        //     this.fillPolylines = this.dv(new CzmPolylines(czmViewer))
        //     const fls = this.fillPolylines;
        //     fls.color = [0, 0, 1, 1]
        //     fls.show = false;
        //     fls.depthTest = true

        //     // @ts-ignore
        //     this.duanmianPolylines = this.dv(new CzmPolylines(czmViewer))
        //     const dm = this.duanmianPolylines;
        //     dm.color = [1, 1, 0, 1]
        //     dm.show = false;
        //     dm.depthTest = false
        // }, 5000);

        // {
        //     const updata = () => {
        //         const czmViewer = this._owner.activeViewer;
        //         if (!czmViewer) return;
        //         // @ts-ignore
        //         this.excavationPolylines = this.dv(new CzmPolylines(czmViewer))
        //         const els = this.excavationPolylines;
        //         els.color = [1, 1, 0, 1]
        //         els.show = false;
        //         els.depthTest = false

        //         // @ts-ignore
        //         this.fillPolylines = this.dv(new CzmPolylines(czmViewer))
        //         const fls = this.fillPolylines;
        //         fls.color = [0, 0, 1, 1]
        //         fls.show = false;
        //         fls.depthTest = false


        //     }
        //     this.dispose(this._owner.activeViewerChanged.don(updata))
        // }


    }
}